home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / Devices & Hardware / NuBus⁄Slot Manager / Slot Look / Slotlook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-14  |  27.4 KB  |  995 lines  |  [TEXT/MPS ]

  1. /*______________________________________________________*/
  2. /*                   Slot Manager GetInfo                     */
  3. /*                          by                          */
  4. /*                  RICHARD P. COLLYER                  */
  5. /*                       01/16/89                       */
  6. /*______________________________________________________*/
  7.  
  8. /*********************************************************************
  9.  
  10.  
  11.  
  12.  File                :    mbGetsInfo.p
  13.  Author                :    GN    08/13/86
  14.  Mod History        :    RPC    02/01/89      convert to MPW 3.0 C interfaces and 
  15.                                              overhalled the user interface.
  16.  
  17.  
  18.  
  19. Well, here is a cheesy sample that checks the slots, and displays a
  20. partial summary of what is in the slots. It doesn't go as far as getting
  21. to the vendor info, that is something I'll fix up later.  It will show
  22. you how to use the slot manager, though.
  23.  
  24. The user interface is hideous, of course.  It uses writelns, doesn't
  25. update, etc.  I'd shoot myself if I tried to ship this, but right now,
  26. it is an in house experiment only.  I'll make it real in my copious free
  27. time (heh, heh).
  28.  
  29. Basically, the slot manager is very flexible.  So much so, that a given
  30. call may not the right one, just one that works.  Since you should never
  31. hard code to a slot number, or even a board id (since you may revise the
  32. board someday, and still want your software to be compatible, typically
  33. you ask the slot manager for sResources, and it will tell you which
  34. slot it finds them in.    An sResource can be thought of as a function
  35. the card can perform.  The board id happens to be the most basic case
  36. of functions - that of being a board. For instance, if you wrote a
  37. terminal app, you don't want to have your app go out and look for one
  38. board id.  That locks you into ONE hardware product. Your app could
  39. better ask the slot manager for a particular sResource that had an
  40. sRsrc_Type of, say,
  41.  
  42. Category  := CatCommunication
  43. cType     := TypModem
  44. DrvrSW    := {don't care - mask this out}
  45. DrvrHw    := {don't care - mask this out}
  46.  
  47. (you can mask out any type, if you don't care what it is)
  48.  
  49. That gets you to a card that can perform the function of a modem.  But, there
  50. are two more fields to the sRsrc_Type - a software driver field and a
  51. hardware driver field. If you wanted to check to see if this modem had a driver
  52. you could talk to (let us imagine there was a Hayes-compatible command sort of 
  53. driver defined), and a driver id had been defined for this particular driver, you 
  54. would check additionally for the the software driver field, say,
  55.  
  56. Category  := CatCommunication
  57. cType     := TypModem
  58. DrvrSW    := DrSWHayes
  59. DrvrHw    := {don't care - mask this out}
  60.  
  61. (in other words specify the Cat, Type, DrSw, and mask out the DrHW)
  62.  
  63. Your app shouldn't care what the underlying hardware is, unless it
  64. absolutely had to, so you could be compatible with future revs of the
  65. board, and even other manufacturer's boards (say, other Hayes compatible
  66. modem cards). You win by not having to rev your app and by actually
  67. expanding the market, by appealing to more customers.
  68.  
  69.  
  70. Who assigns the board ids and sRsrc_Type values?
  71.  
  72. We (MacDTS) keep the database of the values for the Category, Type, Sw and
  73. HW ids, as well as board ids.  We don't make any values public.  If a
  74. developer desired to have values published, the developer would most likely 
  75. do the publishing anyway.  In short, the database is extremely confidential.
  76.  
  77. If you have a dedicated app that must pound on a given card without using a
  78. driver, that is a different matter. Hopefully, though cards have a driver
  79. that you can call without having to worry about the hardware.  That driver can
  80. be in ROM, in an init, or possibly even in the application (although this last
  81. case kind of defeats the purpose of separating the application from the driver). 
  82. If a card manufacturer defines a software interface and publishes
  83. it (for example the Hayes compatible software set), then other developers can 
  84. develop products for it.
  85. */
  86.  
  87.  
  88. #include    <CType.h>
  89. #include    <Quickdraw.h>
  90. #include    <Windows.h>
  91. #include    <OSUtils.h>
  92. #include    <desk.h>
  93. #include    <dialogs.h>
  94. #include    <Errors.h>
  95. #include    <Events.h>
  96. #include    <Memory.h>
  97. #include    <Menus.h>
  98. #include    <SegLoad.h>
  99. #include    <Slots.h>
  100. #include    <ToolUtils.h>
  101.  
  102. extern _DataInit();
  103.  
  104. #define    TRUE            0xFF
  105. #define    FALSE            0
  106. #define    VERSION            1
  107. #define    SR_BIT            0
  108.  
  109. #define    appleID            128            
  110. #define    appleMenu        0
  111. #define    aboutMeCommand    1
  112.  
  113. #define    fileID            129
  114. #define    nine            1
  115. #define    a                2
  116. #define    b                3
  117. #define    c                4
  118. #define    d                5
  119. #define    e                6
  120. #define    General            8
  121. #define    quitCommand     10
  122.  
  123. #define    aboutMeDLOG        128
  124. #define    okButton        1
  125. #define    authorItem        2
  126. #define    languageItem    3
  127.  
  128. int                    yieldTime;
  129. Rect                TotalRect;
  130. WindowPtr            whichWindow, myWindow, myWindow1;
  131. MenuHandle            mymenu1, mymenu2, mymenu0;
  132. EventRecord         myEvent;
  133. Boolean                DoneFlag;
  134. SpBlockPtr            mySpBlockPtr;
  135. SpBlock                mySpBlock;
  136. SInfoRecord            mySInfoRecord;
  137. SInfoRecPtr            mySInfoRecPtr;
  138. FHeaderRec            myFHeaderRec;
  139. Boolean                first;
  140. PicHandle            GenPict, GetPict;
  141. RGBColor            black, white;
  142.  
  143. /*______________________________________________________*/
  144. /*            Convert Decimal numbers to Hex            */
  145. /*______________________________________________________*/
  146. void Dec2Hex(Num, sig)
  147. long    Num, sig;
  148. {
  149.     int                Rem[7], i, Index;
  150.     char            *tempStrPtr, store[256];
  151.     
  152.     tempStrPtr = &store; /* initalize string memory */
  153.     
  154.     drawstring ("          "); /* check for negative number and convert */
  155.     if (Num < 0)
  156.         drawstring ("-");
  157.     Num = abs (Num);
  158.     
  159.     Num = Num & sig; /* dispose of uninteresting bytes */
  160.         
  161.     /* convert Num to an array of base 16 numbers */
  162.     i = 0;
  163.     do {
  164.         Rem[i] = Num % 16;
  165.         Num /= 16;
  166.         ++i;
  167.         } while (Num >= 16);
  168.     Rem[i] = Num;
  169.     
  170.     /* draw the base 16 numbers as the Hex conversion of Num */
  171.     for (Index = i; Index >= 0; --Index)
  172.         switch (Rem[Index]) {
  173.             case 10:
  174.                 drawstring ("A");
  175.                 break;
  176.             case 11:
  177.                 drawstring ("B");
  178.                 break;
  179.             case 12:
  180.                 drawstring ("C");
  181.                 break;
  182.             case 13:
  183.                 drawstring ("D");
  184.                 break;
  185.             case 14:
  186.                 drawstring ("E");
  187.                 break;
  188.             case 15:
  189.                 drawstring ("F");
  190.                 break;
  191.             default:
  192.                 numtostring (Rem[Index], tempStrPtr);
  193.                 drawstring (tempStrPtr);
  194.                 break;
  195.             }
  196.     drawstring ("(hex)");
  197.     return;
  198. }
  199.  
  200. /*______________________________________________________*/
  201. /*            Look up Error code in Resource            */
  202. /*   FindError : Given an error, write out the prompt   */
  203. /*        string, then look up the errors corresponding   */
  204. /*         error string (located in a string resource)    */
  205. /*                     and write it out.                     */
  206. /*______________________________________________________*/
  207. void FindError(error)
  208. int        error;
  209. {
  210.     char    *ErrorString, storage[256];
  211.     int        Index;
  212.     
  213.     ErrorString = &storage;
  214.     
  215.     if (error <= -290 && error >= -293) {
  216.         Index = abs(error) - 289;
  217.         getindstring (ErrorString, 130, Index);
  218.         }
  219.     else if (error <= -300 && error >= -320) {
  220.         Index = abs(error) - 299;
  221.         getindstring (ErrorString, 131, Index);
  222.         }
  223.     else if (error <= -330 && error >= -351) {
  224.         Index = abs(error) - 329;
  225.         getindstring (ErrorString, 132, Index);
  226.         }
  227.     else if (error = -360) {
  228.         Index = 1;
  229.         getindstring (ErrorString, 133, Index);
  230.         }
  231.     else if (error = -400) {
  232.         Index = 1;
  233.         getindstring (ErrorString, 134, Index);
  234.         }
  235.     else if (error <= -500) {
  236.         Index = abs(error) - 499;
  237.         getindstring (ErrorString, 135, Index);
  238.         }
  239.     else {
  240.         numtostring (error, ErrorString);
  241.         drawstring ("(");
  242.         drawstring (ErrorString);
  243.         drawstring (")");
  244.         ErrorString = "some unknown error";
  245.         }
  246.     drawstring (ErrorString);
  247.     return;
  248. }
  249.  
  250. /*______________________________________________________*/
  251. /*            Write out the slot Number                 */
  252. /*______________________________________________________*/
  253. void FindSlot(Ind)
  254. int        Ind;
  255. {
  256.     /* draw which slot is being looked at in the general information window */
  257.     switch (Ind) {
  258.         case 9:
  259.             MoveTo (20,20);
  260.             drawstring ("Slot Number 9 : ");
  261.             break;
  262.         case 10:
  263.             MoveTo (20,40);
  264.             drawstring ("Slot Number A : ");
  265.             break;
  266.         case 11:
  267.             MoveTo (20,60);
  268.             drawstring ("Slot Number B : ");
  269.             break;
  270.         case 12:
  271.             MoveTo (20,80);
  272.             drawstring ("Slot Number C : ");
  273.             break;
  274.         case 13:
  275.             MoveTo (20,100);
  276.             drawstring ("Slot Number D : ");
  277.             break;
  278.         case 14:
  279.             MoveTo (20,120);
  280.             drawstring ("Slot Number E : ");
  281.             break;
  282.         default:
  283.             break;
  284.         }
  285.     return;
  286. }
  287.  
  288. /*______________________________________________________*/
  289. /*          Get the General Slot information            */
  290. /*   fill in the general information window for slots   */
  291. /*                   other than zero                      */
  292. /*______________________________________________________*/
  293. void GenOtherInfo()
  294. {
  295.     int        Index;
  296.     OSErr    err;
  297.     
  298.     for (Index = 9; Index <= 14; ++Index) {
  299.         /* init parameters for SReadInfo */
  300.         mySInfoRecPtr = &mySInfoRecord; /* provide space for results */
  301.         mySpBlockPtr = &mySpBlock;
  302.         mySpBlockPtr->spResult = (long) mySInfoRecPtr;
  303.         mySpBlockPtr->spSlot = Index; /* which slot to look at */
  304.         
  305.         err = SReadInfo (mySpBlockPtr);
  306.         
  307.         if (!err) {
  308.             if (mySInfoRecPtr->siInitStatusA == smEmptySlot) {
  309.                 FindSlot(Index);
  310.                 drawstring ("got initialization error : ");
  311.                 FindError(mySInfoRecord.siInitStatusA);
  312.                 }
  313.             else {
  314.                 EnableItem(mymenu1, Index - 8);
  315.         
  316.                 /* init parameters for sNextTypesRsrc, look for card info of the following type */
  317.                 /* Look in slot (Index) and drawstring the name of the card */
  318.                 mySpBlockPtr = &mySpBlock;
  319.                 mySpBlockPtr->spSlot = Index;
  320.                 mySpBlockPtr->spID = 0;
  321.                 mySpBlockPtr->spExtDev = 0;
  322.                 mySpBlockPtr->spCategory = 1;
  323.                 mySpBlockPtr->spCType = 0;
  324.                 mySpBlockPtr->spDrvrSW = 0;
  325.                 mySpBlockPtr->spDrvrHW = 0;
  326.                 
  327.                 err = SNextTypeSRsrc (mySpBlockPtr);
  328.                 
  329.                 if (!err) {
  330.                     /* init parameters for SGetCString */
  331.                     mySpBlockPtr = &mySpBlock;
  332.                     mySpBlockPtr->spID = 2; /* sRsrc_Name */
  333.  
  334.                     /* write out information */
  335.                     err = SGetCString (mySpBlockPtr);
  336.                     
  337.                     if (!err) {
  338.                         FindSlot(Index);
  339.                         drawstring ((char *) (mySpBlockPtr->spResult));
  340.                         }
  341.                     else {
  342.                         /* report error */
  343.                         FindSlot(Index);
  344.                         drawstring ("Error doing SGetCString : ");
  345.                         FindError (err);
  346.                         }
  347.                     }
  348.                 else {
  349.                     /* report error */
  350.                     FindSlot(Index);
  351.                     drawstring ("Error doing SNextTypeSRsrc : ");
  352.                     FindError (err);
  353.                     }
  354.                 }
  355.             }
  356.         else {
  357.             /* report error */
  358.             FindSlot(Index);
  359.             drawstring ("Error doing SReadInfo : ");
  360.             FindError (err);
  361.             }
  362.         }
  363.     return;
  364. }
  365.  
  366. /*______________________________________________________*/
  367. /*             get screen and put in Pict               */
  368. /*           This is used for update events             */
  369. /*______________________________________________________*/
  370. void getter(currentPICT, theWindow)
  371. PicHandle    *currentPICT;
  372. WindowPtr    *theWindow;
  373. {
  374.     KillPicture (*currentPICT);
  375.     RGBForeColor(&black);
  376.     RGBBackColor(&white);
  377.     *currentPICT = OpenPicture(&(*theWindow)->portRect);
  378.     CopyBits (&(*theWindow)->portBits, &(*theWindow)->portBits,
  379.                 &(*theWindow)->portRect, 
  380.                 &(*theWindow)->portRect, 
  381.                 srcCopy, nil);
  382.     ClosePicture();
  383.     return;
  384. }
  385.  
  386. /*______________________________________________________*/
  387. /*             get Pict and put in screen               */
  388. /*           This is used for update events             */
  389. /*______________________________________________________*/
  390. void putter(currentPICT, theWindow)
  391. PicHandle    *currentPICT;
  392. WindowPtr    *theWindow;
  393. {
  394.     WindowPtr    tempPtr;
  395.     
  396.     GetPort (&tempPtr);
  397.     SetPort (*theWindow);
  398.     DrawPicture (*currentPICT, &(*theWindow)->portRect);
  399.     SetPort (tempPtr);
  400.     return;
  401. }
  402.  
  403. /*______________________________________________________*/
  404. /*              Get General Information                 */
  405. /*    GenInfo : Display the slot information record     */
  406. /*        for all the slots.  Uses the fact that          */
  407. /*       the (required) board resource ALWAYS has         */
  408. /*       an sRsrc_Type of CatBoard, TypeBoard,0,0.        */
  409. /*     The other sRsrc_Types will have different        */
  410. /*          Cat, Typ, drvrsw, and drvrhw.                */
  411. /*______________________________________________________*/
  412. void GenInfo()
  413.  
  414. {
  415.     /* Get information about slots 9 - E */
  416.     
  417.     GenOtherInfo();
  418.  
  419.     /* save window to a PICT for use during updates */
  420.     getter(&GenPict, &myWindow);
  421.     return;
  422. }
  423.  
  424. /*______________________________________________________*/
  425. /*             Get Specific Information                 */
  426. /* GetInfo : Display slot info.
  427.  routines used:
  428.  
  429. theErr := sNextTypesRsrc(myspBlkPtr); {find info only about a specified sResource type}
  430.      INPUT:
  431.      mySpBlock.spSlot      - slot number to start from
  432.      mySpBlock.Id            - sResource list id number to start from
  433.      mySpBlock.spExtDev     -
  434.      mySpBlock.spTBMask     - mask for desired sResource types
  435.      mySpBlock.spCategory - sResource type fields
  436.      mySpBlock.spCType     - sResource type fields
  437.      mySpBlock.spDrvrSW     - sResource type fields
  438.      mySpBlock.spDrvrSW     - sResource type fields
  439.      mySpBlock.spHWDev     -
  440.      RETURNED:
  441.      mySpBlock.spSlot      - slot number of FOUND sResource
  442.      mySpBlock.Id            - sResource list id number
  443.      mySpBlock.spExtDev     -
  444.      mySpBlock.spsPointer -
  445.      mySpBlock.spRefNum     - driver reference number
  446.      mySpBlock.spIOReserved - slot resource table ioReserved field
  447.      mySpBlock.spCategory    - sResource type fields
  448.      mySpBlock.spCType     - sResource type fields
  449.      mySpBlock.spDrvrSW     - sResource type fields
  450.      mySpBlock.spDrvrSW     - sResource type fields
  451.      mySpBlock.spHWDev     -
  452.  
  453. theErr := sRsrcInfo(myspBlkPtr); {usually used to get driver refnum}
  454.      INPUT:
  455.      mySpBlock.spSlot     - slot number
  456.      mySpBlock.Id        - id of the sResource
  457.      mySpBlock.spExtDev     - external device identifier
  458.      RETURNED:
  459.      mySpBlock.spsPointer    - sResource list pointer
  460.      mySpBlock.spCategory    - sResource type fields
  461.      mySpBlock.spCType     - sResource type fields
  462.      mySpBlock.spDrvrSW     - sResource type fields
  463.      mySpBlock.spDrvrSW     - sResource type fields
  464.      mySpBlock.spRefNum     - driver reference number
  465.      mySpBlock.spIOReserved - slot resource table ioReserved field
  466.      mySpBlock.spHWDev     -
  467.  
  468. theErr :=  SReadWord(myspBlkPtr);
  469.       INPUT:
  470.       mySpBlock.spsPointer - pointer to the sResource list
  471.       mySpBlock.spID     - id within that sResource list
  472.       RETURNED:
  473.       mySpBlock.spResult  - the 16 bit value returned in low-order word of spResult (spResult=long)
  474.  
  475. theErr :=  SReadFHeader(myspBlkPtr);
  476.       INPUT:
  477.       mySpBlock.spSlot    - slot number
  478.       mySpBlock.spResult  - point to result area (which is an FHeaderRec)
  479.       RETURNED:
  480.       mySpBlock.spResult  -
  481.       mySpBlock.spResult is a pointer to FHeader record, with the following structure:
  482.       FHeaderRec = PACKED RECORD
  483.         fhDirOffset: LONGINT;    {offset to directory}
  484.         fhLength: LONGINT;     {length of ROM}
  485.         fhCRC: LONGINT;      {CRC}
  486.         fhROMRev: SignedByte;    {revision of ROM}
  487.         fhFormat: SignedByte;    {format - 2}
  488.         fhTstPat: LONGINT;     {test pattern}
  489.         fhReserved: SignedByte;   {reserved}
  490.         fhByteLanes: SignedByte;  {ByteLanes}
  491.         END;
  492.  
  493.       and of course,
  494.       FHeaderRecPtr = ^FHeaderRec;
  495.  
  496. theErr :=  SReadDrvrName(myspBlkPtr);
  497.       INPUT:
  498.       mySpBlock.spSlot    - slot number
  499.       mySpBlock.spID     - id within that sResource list
  500.       mySpBlock.spResult  - the 16 bit value returned in low-order word of spResult (spResult=long)
  501.       RETURNED:
  502.       mySpBlock.spResult  - the 16 bit value returned in low-order word of spResult (spResult=long)
  503.  
  504. ________________________________________________________*/
  505. void GetInfo(WhichSlot)
  506. int        WhichSlot;
  507. {
  508.     OSErr            err;
  509.     FHeaderRecPtr    tempFHeaderRecPtr;
  510.     char            *tempStrPtr, NameStr[256], store[256];
  511.     int                temp;
  512.     
  513.     tempStrPtr = &store; /* initalize temperary string varible */
  514.     
  515.     if (first) {
  516.         /* If window hasn't been opened before than open it */
  517.         myWindow1 = GetNewWindow(131, nil, (WindowPtr) -1);
  518.         SetPort (myWindow1);
  519.         first = FALSE;
  520.         }
  521.     else {
  522.         /* If window is already open then make it the front most window */
  523.         SelectWindow (myWindow1);
  524.         SetPort (myWindow1);
  525.         EraseRect (&(myWindow1->portRect));
  526.         }
  527.     
  528.     MoveTo (20,20);
  529.     drawstring ("SLOT INFORMATION for Slot ");
  530.     switch (WhichSlot) {
  531.         case 9:
  532.             drawstring (" 9 : ");
  533.             break;
  534.         case 10:
  535.             drawstring (" A : ");
  536.             break;
  537.         case 11:
  538.             drawstring (" B : ");
  539.             break;
  540.         case 12:
  541.             drawstring (" C : ");
  542.             break;
  543.         case 13:
  544.             drawstring (" D : ");
  545.             break;
  546.         case 14:
  547.             drawstring (" E : ");
  548.             break;
  549.         default:
  550.             break;
  551.         }
  552.     
  553.     if (WhichSlot != 0) {
  554.         mySpBlockPtr = &mySpBlock;
  555.         mySpBlockPtr->spSlot = WhichSlot;
  556.         mySpBlockPtr->spResult = (long) &myFHeaderRec;
  557.         
  558.         err = SReadFHeader (mySpBlockPtr);
  559.         
  560.         if (!err) {
  561.             /* drawstring the Format Header information listed in reverse order from */
  562.             /* Cards and Driver book Fig 8-3 page 8-5 (Firmware Structure) */
  563.             tempFHeaderRecPtr = (FHeaderRecPtr) mySpBlock.spResult;
  564.             
  565.             MoveTo (20,40);
  566.             drawstring ("fhDirOffset = ");
  567.             numtostring (tempFHeaderRecPtr->fhDirOffset, tempStrPtr);
  568.             drawstring (tempStrPtr);
  569.             Dec2Hex (tempFHeaderRecPtr->fhDirOffset, 0xFFFFFFFF);
  570.  
  571.             MoveTo (20,60);
  572.             drawstring ("fhLength = ");
  573.             numtostring (tempFHeaderRecPtr->fhLength, tempStrPtr);
  574.             drawstring (tempStrPtr);
  575.             Dec2Hex (tempFHeaderRecPtr->fhLength, 0xFFFFFFFF);
  576.  
  577.             MoveTo (20,80);
  578.             drawstring ("fhCRC = ");
  579.             numtostring (tempFHeaderRecPtr->fhCRC, tempStrPtr);
  580.             drawstring (tempStrPtr);
  581.             Dec2Hex (tempFHeaderRecPtr->fhCRC, 0xFFFFFFFF);
  582.  
  583.             MoveTo (20,100);
  584.             drawstring ("fhROMRev = ");
  585.             numtostring (tempFHeaderRecPtr->fhROMRev, tempStrPtr);
  586.             drawstring (tempStrPtr);
  587.             Dec2Hex (tempFHeaderRecPtr->fhROMRev, 0xFFFFFFFF);
  588.  
  589.             MoveTo (20,120);
  590.             drawstring ("fhFormat = ");
  591.             numtostring (tempFHeaderRecPtr->fhFormat, tempStrPtr);
  592.             drawstring (tempStrPtr);
  593.             Dec2Hex (tempFHeaderRecPtr->fhFormat, 0xFFFFFFFF);
  594.  
  595.             MoveTo (20,140);
  596.             drawstring ("fhTstPat = ");
  597.             numtostring (tempFHeaderRecPtr->fhTstPat, tempStrPtr);
  598.             drawstring (tempStrPtr);
  599.             Dec2Hex (tempFHeaderRecPtr->fhTstPat, 0xFFFFFFFF);
  600.  
  601.             MoveTo (20,160);
  602.             drawstring ("fhReserved = ");
  603.             numtostring (tempFHeaderRecPtr->fhReserved, tempStrPtr);
  604.             drawstring (tempStrPtr);
  605.             Dec2Hex (tempFHeaderRecPtr->fhReserved, 0xFFFFFFFF);
  606.  
  607.             MoveTo (20,180);
  608.             drawstring ("fhByteLanes = ");
  609.             temp = tempFHeaderRecPtr->fhByteLanes & 0x000000FF;
  610.             numtostring (temp, tempStrPtr);
  611.             drawstring (tempStrPtr);
  612.             Dec2Hex (temp, 0x000000FF);
  613.             }
  614.         else {
  615.             /* report error */
  616.             MoveTo (20,40);
  617.             drawstring ("Error doing SReadFHeader : ");
  618.             FindError (err);
  619.             }
  620.  
  621.         mySpBlockPtr = &mySpBlock;
  622.         mySpBlockPtr->spSlot = WhichSlot;
  623.         mySpBlockPtr->spID = 128; /* bogas hard coding, assumes only one functional resource */
  624.         /* I should use sNextsRsrc call and look for all functional resources, maybe in the next rev*/
  625.         mySpBlockPtr->spResult = NameStr; /* provide space for card's name */
  626.             
  627.         err = SReadDrvrName (mySpBlockPtr);
  628.             
  629.         if (!err) {
  630.             MoveTo (20,200);
  631.             drawstring ("The driver name is: ");
  632.             DrawString (NameStr);
  633.             }
  634.         else {
  635.             MoveTo (20,200);
  636.             drawstring ("Error doing SReadDrvrName : ");
  637.             FindError (err);
  638.             }
  639.         }
  640.         
  641.     mySpBlockPtr = &mySpBlock;
  642.     mySpBlockPtr->spSlot = WhichSlot;
  643.     mySpBlockPtr->spID = 0;
  644.     mySpBlockPtr->spExtDev = 0;
  645.     mySpBlockPtr->spCategory = 1;
  646.     mySpBlockPtr->spCType = 0;
  647.     mySpBlockPtr->spDrvrSW = 0;
  648.     mySpBlockPtr->spDrvrHW = 0;
  649.     
  650.     err = SNextTypeSRsrc (mySpBlockPtr);
  651.     
  652.     if (!err) {
  653.         mySpBlockPtr->spID = 32; /* look for Board ID card design id#, See page 8-17 Cards and Drivers */
  654.         err = SReadWord (mySpBlockPtr);
  655.         
  656.         if (!err) {
  657.             MoveTo (20,220);
  658.             drawstring ("The Board id is: ");
  659.             temp = mySpBlockPtr->spResult & 0x0000FFFF;
  660.             numtostring (temp, tempStrPtr);
  661.             drawstring (tempStrPtr);
  662.             Dec2Hex (mySpBlockPtr->spResult, 0x0000FFFF);
  663.             
  664.             MoveTo (20,240);
  665.             drawstring ("The Board is: ");
  666.                 
  667.             mySpBlockPtr = &mySpBlock;
  668.             mySpBlockPtr->spID = 2; /* sRsrc_Name, Name of the sResource */
  669.             
  670.             err = SGetCString (mySpBlockPtr);
  671.             if (!err)
  672.                 drawstring ((char *) mySpBlockPtr->spResult);
  673.             
  674.             mySpBlockPtr = &mySpBlock;
  675.             mySpBlockPtr->spID = 36; /* Vendor part number, name, and so forth */
  676.             
  677.             if (WhichSlot != 0) {
  678.                 err = SFindStruct (mySpBlockPtr);
  679.                 
  680.                 if (!err) {
  681.                     /* The following is stored in the VendorInfo field of the Board sResource */
  682.                     /* for more information about the VendorInfo field see page 8-19 of the */
  683.                     /* Cards and Drivers manual */
  684.                     MoveTo (20,260);
  685.                     mySpBlockPtr = &mySpBlock;
  686.                     mySpBlockPtr->spID = 1; /* the card vendor's design identification */
  687.                     err = SGetCString (mySpBlockPtr);
  688.                     if (!err) {
  689.                         drawstring ("Vendor ID is : ");
  690.                         drawstring ((char *) mySpBlockPtr->spResult);
  691.                         }
  692.                     else {
  693.                         drawstring ("Error doing SGetCString : ");
  694.                         FindError (err);
  695.                         }
  696.                     
  697.                     MoveTo (20,280);
  698.                     mySpBlockPtr = &mySpBlock;
  699.                     mySpBlockPtr->spID = 2; /* the individual card's serial number */
  700.                     err = SGetCString (mySpBlockPtr);
  701.                     if (!err) {
  702.                         drawstring ("Serial Num is : ");
  703.                         drawstring ((char *) mySpBlockPtr->spResult);
  704.                         }
  705.                     else {
  706.                         drawstring ("Error doing SGetCString : ");
  707.                         FindError (err);
  708.                         }
  709.                     
  710.                     MoveTo (20,300);
  711.                     mySpBlockPtr = &mySpBlock;
  712.                     mySpBlockPtr->spID = 3; /* the card design's revision level */
  713.                     err = SGetCString (mySpBlockPtr);
  714.                     if (!err) {
  715.                         drawstring ("Rev Level is : ");
  716.                         drawstring ((char *) mySpBlockPtr->spResult);
  717.                         }
  718.                     else {
  719.                         drawstring ("Error doing SGetCString : ");
  720.                         FindError (err);
  721.                         }
  722.                     
  723.                     MoveTo (20,320);
  724.                     mySpBlockPtr = &mySpBlock;
  725.                     mySpBlockPtr->spID = 4; /* the part number of the card */
  726.                     err = SGetCString (mySpBlockPtr);
  727.                     if (!err) {
  728.                         drawstring ("Part Num is : ");
  729.                         drawstring ((char *) mySpBlockPtr->spResult);
  730.                         }
  731.                     else {
  732.                         drawstring ("Error doing SGetCString : ");
  733.                         FindError (err);
  734.                         }
  735.                     
  736.                     MoveTo (20,340);
  737.                     mySpBlockPtr = &mySpBlock;
  738.                     mySpBlockPtr->spID = 5; /* last revision date of the card */
  739.                     err = SGetCString (mySpBlockPtr);
  740.                     if (!err) {
  741.                         drawstring ("Date is : ");
  742.                         drawstring ((char *) mySpBlockPtr->spResult);
  743.                         }
  744.                     else {
  745.                         drawstring ("Error doing SGetCString : ");
  746.                         FindError (err);
  747.                         }
  748.                     }
  749.                 else {
  750.                     MoveTo (20,260);
  751.                     drawstring ("Error doing sFindStruct : ");
  752.                     FindError (err);
  753.                     }
  754.                 }
  755.             }
  756.         else {
  757.             MoveTo (20,220);
  758.             drawstring ("Error doing SReadWord : ");
  759.             FindError (err);
  760.             }
  761.         }
  762.     else {
  763.         MoveTo (20,220);
  764.         drawstring ("Error doing sNextTypesRscr : ");
  765.         FindError (err);
  766.         }
  767.     getter(&GetPict, &myWindow1);
  768.     return;
  769. }
  770.  
  771. /*______________________________________________________*/
  772. /*                 About Prog Dialog                    */
  773. /*______________________________________________________*/
  774. void showAboutMeDialog()
  775. {
  776.     GrafPtr     savePort;
  777.     DialogPtr    theDialog;
  778.     short        itemHit;
  779.  
  780.     GetPort(&savePort);
  781.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  782.     SetPort(theDialog);
  783.  
  784.     do {
  785.         ModalDialog(nil, &itemHit);
  786.     } while (itemHit != okButton);
  787.  
  788.     CloseDialog(theDialog);
  789.  
  790.     SetPort(savePort);
  791.     return;
  792. }
  793.  
  794. /*______________________________________________________*/
  795. /*                 Do Menu Function                     */
  796. /*______________________________________________________*/
  797. void doCommand(mResult)
  798.     long    mResult;
  799. {
  800.     int                     theMenu, theItem;
  801.     char                    daName[256];
  802.     GrafPtr                 savePort;
  803.  
  804.     theItem = LoWord(mResult);
  805.     theMenu = HiWord(mResult);
  806.     
  807.     switch (theMenu) {
  808. /*______________________________________________________*/
  809. /*                    Do Apple Menu                     */
  810. /*______________________________________________________*/
  811.         case appleID:
  812.             if (theItem == aboutMeCommand)
  813.                 showAboutMeDialog();
  814.             else {
  815.                 GetItem(mymenu0, theItem, daName);
  816.                 GetPort(&savePort);
  817.                 (void) OpenDeskAcc(daName);
  818.                 SetPort(savePort);
  819.             }
  820.             break;
  821. /*______________________________________________________*/
  822. /*                     Do File Menu                     */
  823. /*______________________________________________________*/
  824.         case fileID:
  825.             switch (theItem) {
  826.                 case nine:
  827.                     GetInfo(9);
  828.                     break;
  829.                 case a:
  830.                     GetInfo(10);
  831.                     break;
  832.                 case b:
  833.                     GetInfo(11);
  834.                     break;
  835.                 case c:
  836.                     GetInfo(12);
  837.                     break;
  838.                 case d:
  839.                     GetInfo(13);
  840.                     break;
  841.                 case e:
  842.                     GetInfo(14);
  843.                     break;
  844.                 case General:
  845.                     SelectWindow(myWindow);
  846.                     SetPort((WindowPtr) myWindow);
  847.                     GenInfo();
  848.                     break;
  849.                 case quitCommand:
  850.                     DoneFlag = TRUE;
  851.                     break;
  852.                 default:
  853.                     break;
  854.                 }
  855.             break;
  856.         default:
  857.             break;
  858.         }
  859.     HiliteMenu(0);
  860.     return;
  861. }
  862.  
  863. /*______________________________________________________*/
  864. /*               Initialization traps                   */
  865. /*______________________________________________________*/
  866. void init()
  867. {
  868.     RgnHandle        tempRgn;
  869.     
  870.     UnloadSeg(_DataInit);
  871.     InitGraf(&qd.thePort);
  872.     FlushEvents(everyEvent, 0);
  873.     InitWindows();
  874.     InitDialogs(nil);
  875.     InitCursor();
  876.             
  877. /*______________________________________________________*/
  878. /*                     Set Rects                        */
  879. /*______________________________________________________*/
  880.     tempRgn = GetGrayRgn();
  881.     HLock ((Handle) tempRgn);
  882.     TotalRect = (**tempRgn).rgnBBox; /* this rect is used for DragWindow call */
  883.     HUnlock ((Handle) tempRgn);
  884.  
  885. /*______________________________________________________*/
  886. /*                    Set menus                         */
  887. /*______________________________________________________*/
  888.     mymenu0 = GetMenu(appleID);
  889.     AddResMenu(mymenu0, 'DRVR');
  890.     InsertMenu(mymenu0,0);
  891.     mymenu1 = GetMenu(129);
  892.     InsertMenu(mymenu1,0);
  893.     DrawMenuBar();
  894.  
  895. /*______________________________________________________*/
  896. /*                  Init variables                      */
  897. /*______________________________________________________*/
  898.     /* define black and white of copybits call */
  899.     black.red = 0;
  900.     black.green = 0;
  901.     black.blue = 0;
  902.     white.red = 65535;
  903.     white.green = 65535;
  904.     white.blue = 65535;
  905.     DoneFlag = FALSE;
  906.     first = TRUE;
  907.     yieldTime = 0;
  908.     return;
  909. }
  910.  
  911. main()
  912. {
  913.     Boolean        track;
  914.     char        key;
  915. /*______________________________________________________*/
  916. /*                   Main Event loop                    */
  917. /*______________________________________________________*/
  918.     init();
  919.     myWindow = GetNewWindow(130, nil, (WindowPtr) -1);
  920.     SetPort((WindowPtr) myWindow);
  921.     GenInfo();
  922.     for ( ;; ) {
  923.         if (DoneFlag) {
  924.             ExitToShell();
  925.             }
  926.         if (WaitNextEvent(everyEvent, &myEvent, yieldTime, nil)) {
  927.             switch (myEvent.what) {
  928.                 case mouseDown:
  929.                     switch (FindWindow(myEvent.where, &whichWindow)) {
  930.                         case inSysWindow:
  931.                             SystemClick(&myEvent, whichWindow);
  932.                             break;
  933.                         case inMenuBar:
  934.                             doCommand(MenuSelect(myEvent.where));
  935.                             break;
  936.                         case inContent:
  937.                             if (whichWindow == myWindow)
  938.                                 SelectWindow (myWindow);
  939.                             if (whichWindow == myWindow1)
  940.                                 SelectWindow (myWindow1);
  941.                             break;
  942.                         case inDrag:
  943.                             DragWindow (whichWindow, myEvent.where, &TotalRect);
  944.                             break;
  945.                         case inGoAway:
  946.                             track = TrackGoAway (whichWindow, myEvent.where);
  947.                             if (track)
  948.                                 CloseWindow (whichWindow);
  949.                             break;
  950.                         default:
  951.                             break;
  952.                         }
  953.                     break;
  954.                 case keyDown:
  955.                 case autoKey:
  956.                     key = myEvent.message & charCodeMask;
  957.                     if ( myEvent.modifiers & cmdKey )
  958.                         if ( myEvent.what == keyDown )
  959.                             doCommand(MenuKey(key));
  960.                     break;
  961.                 case updateEvt:
  962.                     if ((WindowPtr) myEvent.message == myWindow) {
  963.                         /* Update General Information Window */
  964.                         BeginUpdate((WindowPtr) myWindow);
  965.                         putter(&GenPict, &myWindow);
  966.                         EndUpdate((WindowPtr) myWindow);
  967.                         }
  968.                     if ((WindowPtr) myEvent.message == myWindow1) {
  969.                         /* Update Specific Inforamtion Window */
  970.                         BeginUpdate((WindowPtr) myWindow1);
  971.                         putter(&GetPict, &myWindow1);
  972.                         EndUpdate((WindowPtr) myWindow1);
  973.                         }
  974.                     break;
  975.                 case diskEvt:
  976.                     break;
  977.                 case activateEvt:
  978.                     break;
  979.                 case app4Evt:
  980.                     if ((myEvent.message << 31) == 0) { /* Suspend */
  981.                         yieldTime = 30;
  982.                         HideWindow((WindowPtr) myWindow);
  983.                         }
  984.                     else { /* Resume */
  985.                         yieldTime = 0;
  986.                         ShowWindow((WindowPtr) myWindow);
  987.                         SetPort((WindowPtr) myWindow);
  988.                         }
  989.                     break;
  990.                 default:
  991.                     break;
  992.                 }
  993.             }
  994.         }
  995. }